/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package modbus;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.ResourceBundle.Control;
import java.util.logging.Level;
import java.util.logging.Logger;
import ui.Controlador;

/**
 * Hilo que maneja la transmisión/recepción
 * @author Leandro && Luquitas
 */
public class ExpertoComunicacion extends Thread {

    private Driver driver;
    private boolean enviar = false;
    private boolean cortar = false;
    private Paquete p;
    private List<Paquete> ps;
    private int intervalo = 1000;

    public List<Paquete> getPs() {
        return ps;
    }

    public void setPs(List<Paquete> ps) {
        this.ps = ps;
    }

    public int getIntervalo() {
        return intervalo;
    }

    public void setIntervalo(int intervalo) {
        this.intervalo = intervalo;
    }

    public boolean isEnviar() {
        return enviar;
    }

    public void setEnviar(boolean enviar) {
        this.enviar = enviar;
    }

    public Paquete getP() {
        return p;
    }

    public void setP(Paquete p) {
        this.p = p;
    }

    public boolean isCortar() {
        return cortar;
    }

    public void setCortar(boolean cortar) {
        this.cortar = cortar;
    }

    public ExpertoComunicacion(Driver driver) {
        this.driver = driver;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver(Driver driver) {
        this.driver = driver;
    }

    private byte[] recibir() {
        byte[] buffer = new byte[1024];
        int len = -1, i, temp;
        int cantInt = 0;
        boolean recibi = true;
        byte[] aux = null;
        String aux1 = "";
        if (driver != null) {
            do {
                aux = driver.receive();
                if (aux == null) {
                    //Logica de reintentos
                    cantInt++;
                    recibi = false;
                    SuscriptorMensajes.getI().notificar("Reintento N°:" + (cantInt - 1));
                    try {
                        SuscriptorMensajes.getI().notificar("A Dormir ...");
                        sleep(driver.getTimeout());
                    } catch (InterruptedException ex) {
                        Logger.getLogger(DriverSerie.class.getName()).log(Level.SEVERE, null, ex);
                        SuscriptorMensajes.getI().notificar("Excepcion tratando de dormir");
                    }
                }
            } while (cantInt < driver.getNroReintentos() && !recibi);
            if (!recibi) {
                SuscriptorMensajes.getI().notificar("Error en la recepcion, cantidad de intentos agotados");
            }
        }
        int inicial=0;
        if(driver instanceof DriverSerie){
            inicial=1;
        }else if(driver instanceof DriverTCP){
            inicial=7;
        }
        if (aux[inicial] == (byte) 131 || aux[inicial] == (byte) 134 || aux[inicial] == (byte) 144) {
            //Devolvió un error
            SuscriptorMensajes.getI().notificar("ERROR:Error Code= " + Integer.toHexString(0x000000FF & aux[1]) + " Ex code = " + Integer.toHexString(0x000000FF & aux[2]));
        } else {
            //Notificación a los observadores
            for (i = 0; i < aux.length; i++) {
                if (Controlador.getSistemaNum() == 'H') {
                    aux1 += "[" + Integer.toHexString(0x000000FF & aux[i]) + "]";
                } else {
                    aux1 += "[" + aux[i] + "]";
                }

                System.out.print("[" + aux[i] + "]");
            }
            System.out.println("");
            SuscriptorMensajes.getI().notificar("RX:" + aux1);
            int extra=5;
            int offset=3;
            if(driver instanceof  DriverTCP){
                extra=9;
                offset=9;
            }
            byte[] vars=new byte[aux.length-extra];
            for(int j=0;j<vars.length;j++){
                vars[j]=aux[j+offset];
            }
            SuscriptorMensajes.getI().notificarVar(vars);
        }
        return aux;
    }

    public void enviar(Paquete p) {


        driver.send(p);
        String aux = "";
        byte[] paquete = null;
        if(driver instanceof DriverSerie){
            paquete= p.getPaqueteSerial();
        }else if(driver instanceof DriverTCP){
            paquete=p.getPaqueteTCP();
        }
        for (byte b : paquete) {
            if (Controlador.getSistemaNum() == 'H') {
                aux += "[" + Integer.toHexString(0x000000FF & b) + "]";
            } else {
                aux += "[" + b + "]";
            }
            System.out.print("[" + b + "]");
        }
        SuscriptorMensajes.getI().notificar("TX:" + aux);
        System.out.println("");
    }

    public void run() {
        if(driver!=null){
            driver.setExpertoComunicaciones(this);
        }
        while (true) {

            if (driver != null && enviar) {

                for (Paquete p : ps) {

                    try {
                        System.out.println("Iniciando envio");
                        SuscriptorMensajes.getI().notificar("Iniciando envío");
                        enviar(p);
                        Thread.sleep(intervalo);   //Agregar evento de notificacion cuando llega paquete
                        //this.wait(intervalo);
                        System.out.println("Iniciando recepción");
                        SuscriptorMensajes.getI().notificar("Iniciando recepción");
                        recibir();
                        Thread.sleep(intervalo);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(ExpertoComunicacion.class.getName()).log(Level.SEVERE, null, ex);
                        System.out.println("No pude dormir");
                        SuscriptorMensajes.getI().notificar("No pudo dormir");
                    }
                }
            }

        }
    }
}
